package ticketingsystem;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

public class TicketingDS implements TicketingSystem {

    private Train[] trains;
    private AtomicInteger ticketID;
    private ConcurrentHashMap<Long, Ticket> soldTicket;
    public TicketingDS(int routenum, int coachnum, int seatnum, int stationnum, int threadnum){
        trains = new Train[routenum];
        ticketID = new AtomicInteger(1);
        for(int i = 0; i < routenum; i++){
            trains[i] = new Train(coachnum, seatnum, stationnum);
        }
        soldTicket = new ConcurrentHashMap<Long, Ticket>();
    }

    @Override
    public Ticket buyTicket(String passenger, int route, int departure, int arrival) {
        int seat = trains[route - 1].lockSeat(departure - 1, arrival - 1);
        if(seat < 0){
            return null;
        }
        Ticket ticket = new Ticket();
        ticket.tid = ticketID.getAndIncrement();
        ticket.passenger = passenger;
        ticket.route = route;
        ticket.departure = departure;
        ticket.arrival = arrival;
        ticket.coach = (seat / ((trains[route - 1].seatNum >> 3) / trains[route - 1].coachNum)) + 1;
        ticket.seat = (seat % ((trains[route - 1].seatNum >> 3) / trains[route - 1].coachNum)) + 1;
        if(ticket.seat == 0){
            System.out.println(seat + "\t" + trains[route -1].seatNum);
        }
        soldTicket.put(ticket.tid, ticket);
        return ticket;
    }

    @Override
    public int inquiry(int route, int departure, int arrival) {
        return trains[route - 1].querySeat(departure - 1, arrival - 1);
    }

    @Override
    public boolean refundTicket(Ticket ticket) {
        if(!soldTicket.containsKey(ticket.tid) || !ticket.equals(soldTicket.get(ticket.tid))){
            return false;
        }
        int seat = (ticket.coach - 1) * (trains[ticket.route - 1].seatNum / trains[ticket.route - 1].coachNum) + (ticket.seat - 1);
        if(seat == -1) {
            System.out.println(seat + "\t(" + ticket.coach + "-1)*" + trains[ticket.route - 1].seatNum + "+(" + ticket.seat + "-1)");
        }

        if(trains[ticket.route - 1].unlockSeat(seat, ticket.departure - 1, ticket.arrival - 1)){
            return soldTicket.remove(ticket.tid, ticket);
        }
        return false;
    }
}
